package com.sisgesbyte.services.proyeccion;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;

import com.sisgesbyte.common.ConstModAdministracion;
import com.sisgesbyte.common.ConstProyeccion;
import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.administracion.MantCategoriaProductoDao;
import com.sisgesbyte.dao.administracion.MantenimientoMarcaDao;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.dao.beanDao.ProyeccionZonaDetallaRequest;
import com.sisgesbyte.dao.proyeccion.MantProyeccionZonaDao;
import com.sisgesbyte.dao.proyeccion.MantProyeccionZonaDetalleDao;
import com.sisgesbyte.data.entity.administracion.CategoriaProductoEntity;
import com.sisgesbyte.data.entity.administracion.MarcaEntity;
import com.sisgesbyte.data.entity.comun.GenericEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionZonaDetalleEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionZonaEntity;
import com.sisgesbyte.services.commonBean.GenericResponse;
import com.sisgesbyte.services.proyeccion.bean.FiltroOpcionesCanalBean;
import com.sisgesbyte.services.proyeccion.bean.FiltroProductoZonaBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyCategoriaClienteResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyZonasCategoriaResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyZonasMarcasResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionZonaResponse;
import com.sisgesbyte.services.proyeccion.bean.ProyGeneralCategoriaBean;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionCategoriaClienteBean;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionGeneralMarcasBean;
import com.sisgesbyte.services.proyeccion.bean.ZonaProyeccionBean;

@Stateless
public class MantProyeccionZonaServiceImpl implements MantProyeccionZonaService {

	@EJB
	private MantProyeccionZonaDao mantProyeccionZonaDao;
	@EJB
	private MantProyeccionZonaDetalleDao mantProyeccionZonaDetalleDao;
	@EJB
	private MantProyeccionCanalService mantProyeccionCanalService;
	@EJB
	private MantenimientoMarcaDao mantenimientoMarcaDao;
	@EJB
	private MantCategoriaProductoDao mantCategoriaProductoDao;
	private List<CategoriaProductoEntity> listaHijosCategoriaProd;
	private List<CategoriaProductoEntity> hijos;
	
	@Inject
	private Validaciones validaciones;
	
	@Override
	public ListaProyeccionZonaResponse listaProyeccionZonas( String codTransaccion, FiltroProductoZonaBean filtroBean) {
		
		String mensajeTransaccionMetodo = "[listaProyeccionZonas idTx=" + codTransaccion + "] - ";
		ListaProyeccionZonaResponse response = new ListaProyeccionZonaResponse();
		
		List<ProyeccionZonaEntity> responseDao = null; 
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();
			//filtro por periodo
			if(filtroBean.getIdPeriodo() > 0){
				FiltrosBean listaPeriodo = new FiltrosBean();
				List<String> campoPeriodo = new ArrayList<String>();
				campoPeriodo.add("pz.periodo_id");
				listaPeriodo.setCampos(campoPeriodo);
				listaPeriodo.setOperador("=");
				filtro.add(listaPeriodo);
				valores.add(filtroBean.getIdPeriodo());
			}
			//filtro por zona
			if(filtroBean.getIdZona() > 0){
				FiltrosBean listaZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("pz.zona_id");
				listaZona.setCampos(campoZona);
				listaZona.setOperador("=");
				filtro.add(listaZona);
				valores.add(filtroBean.getIdZona());
			}
			
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			
			responseDao = mantProyeccionZonaDao.listaProyeccionZona(filtroSQL);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		List<ZonaProyeccionBean> listaProyeccionZona = new ArrayList<ZonaProyeccionBean>();
		for(ProyeccionZonaEntity lista : responseDao){
			ZonaProyeccionBean bean = new ZonaProyeccionBean();
			bean.setBandaGeneral(validaciones.validarCamposString(lista.getBanda_general()));
			bean.setBandaPeriodo(validaciones.validarCamposString(lista.getBanda_periodo()));
			bean.setId(lista.getId());
			bean.setMontoPeriodo(lista.getMonto_periodo());
			bean.setPeriodoId(lista.getPeriodo_id());
			bean.setPeriodo(validaciones.validarCamposString(lista.getPeriodo()));
			bean.setZona(validaciones.validarCamposString(lista.getZona()));
			bean.setZonaId(lista.getZona_id());
			BigDecimal totalZona = BigDecimal.ZERO;
			try{
				FiltroOpcionesCanalBean filtro = new FiltroOpcionesCanalBean();
				filtro.setPeriodoId(lista.getPeriodo_id());
				filtro.setZonaId(lista.getZona_id());
				filtro.setCanalId(0);
				ListaProyCategoriaClienteResponse proyeccionCanal = mantProyeccionCanalService.listaCatClientes(codTransaccion, filtro);
				if(proyeccionCanal.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					for(ProyeccionCategoriaClienteBean listaCanal :proyeccionCanal.getListaProyeccionCategoriaCliente()){
						totalZona =totalZona.add(listaCanal.getMontoProyectado());
					}
				}
			}catch(Exception e){
				totalZona =  BigDecimal.ZERO;
			}
			bean.setMontoProyectadoPeriodo(totalZona);
			int val = lista.getMonto_periodo().compareTo(totalZona);
		    if( val == 0 ){
		    	bean.setColorMontoProyectado(ConstProyeccion.COLOR_VERDE);
		    }else if( val == 1 ){
		    	bean.setColorMontoProyectado(ConstProyeccion.COLOR_ROJO);
		    }
		    else if( val == -1 ){
		    	bean.setColorMontoProyectado(ConstProyeccion.COLOR_AMARILLO);
		    };
			
			listaProyeccionZona.add(bean);
		}
		
		if(listaProyeccionZona.size() > 0){
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyeccionZona(listaProyeccionZona);
		} else {
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
		}
		return response;
	}

	@Override
	public GenericResponse nuevaProyeccionZona(String codTransaccion,
			ZonaProyeccionBean request) {
		String mensajeTransaccionMetodo = "[nuevaProyeccionZona idTx=" + codTransaccion + "] - ";
		
		GenericResponse response = new GenericResponse();
		GenericEntity responseDao = null;
		try{
			ProyeccionZonaDetallaRequest req = new ProyeccionZonaDetallaRequest();
			req.setIdZona(request.getZonaId());
			req.setIdPeriodo(request.getPeriodoId());
			req.setCodigoBanda(validaciones.validarCamposString(request.getBandaPeriodo()));
			req.setMontoProyectado(request.getMontoPeriodo());
			responseDao = mantProyeccionZonaDao.guardarProyeccionZona(req);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		
		if (responseDao.getCod_error() == Integer.parseInt(ConstantesInternasSistema.CODIGO_EXITO)) {
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
		} else {
			response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
			response.setMensajeRespuesta(responseDao.getMsj_error());
		}
		
		return response;
	}

	@Override
	public GenericResponse editarProyeccionZona(String codTransaccion,
			ZonaProyeccionBean request) {
		String mensajeTransaccionMetodo = "[editarProyeccionZona idTx=" + codTransaccion + "] - ";
		
		GenericResponse response = new GenericResponse();
		GenericEntity responseDao = null;
		try{
			ProyeccionZonaDetallaRequest req = new ProyeccionZonaDetallaRequest();
			req.setId(request.getId());
			req.setIdZona(request.getZonaId());
			req.setIdPeriodo(request.getPeriodoId());
			req.setCodigoBanda(validaciones.validarCamposString(request.getBandaPeriodo()));
			req.setMontoProyectado(request.getMontoPeriodo());
			responseDao = mantProyeccionZonaDao.actualizarProyeccionZona(req);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		
		if (responseDao.getCod_error() == Integer.parseInt(ConstantesInternasSistema.CODIGO_EXITO)) {
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
		} else {
			response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
			response.setMensajeRespuesta(responseDao.getMsj_error());
		}
		
		return response;
	}

	@Override
	public GenericResponse deleteProyeccionZona(String codTransaccion,
			int codProyeccion) {
		String mensajeTransaccionMetodo = "[deleteProyeccionZona idTx=" + codTransaccion + "] - ";
		
		GenericResponse response = new GenericResponse();
		GenericEntity responseDao = null;
		try{
			responseDao = mantProyeccionZonaDao.eliminarProyeccionZona(codProyeccion);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
		}
		
		if (responseDao.getCod_error() == Integer.parseInt(ConstantesInternasSistema.CODIGO_EXITO)) {
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
		} else {
			response.setCodigoRespuesta(String.valueOf(responseDao.getCod_error()));
			response.setMensajeRespuesta(responseDao.getMsj_error());
		}
		return response;
	}

	@Override
	public ListaProyZonasMarcasResponse mostrarProyZonaMarcas( String codTransaccion, FiltroProductoZonaBean filtrosBean) {
		
		String mensajeTransaccionMetodo = "[mostrarProyZonaMarcas idTx=" + codTransaccion + "] - ";
		ListaProyZonasMarcasResponse response = new ListaProyZonasMarcasResponse();
		
		if(filtrosBean.getIdPeriodo() < 1){
			System.out.println("Seleccionar periodo ");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
			return response;
		}
		if(filtrosBean.getIdZona() < 1){
			System.out.println("Seleccionar zona ");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
			return response;
		}
		
		List<ProyeccionZonaDetalleEntity> listaProdZona = null;
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();
			//filtro por periodo
			if(filtrosBean.getIdPeriodo() > 0){
				FiltrosBean listaPeriodo = new FiltrosBean();
				List<String> campoPeriodo = new ArrayList<String>();
				campoPeriodo.add("pz.periodo_id");
				listaPeriodo.setCampos(campoPeriodo);
				listaPeriodo.setOperador("=");
				filtro.add(listaPeriodo);
				valores.add(filtrosBean.getIdPeriodo());
			}
			//filtro por zona
			if(filtrosBean.getIdZona() > 0){
				FiltrosBean listaZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("pz.zona_id");
				listaZona.setCampos(campoZona);
				listaZona.setOperador("=");
				filtro.add(listaZona);
				valores.add(filtrosBean.getIdZona());
			}
			
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			//1.- cargamos la lista de productos por zona y periodo
			listaProdZona = mantProyeccionZonaDetalleDao.listaProyeccionZonaDetalle(filtroSQL);
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar productos de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		List<MarcaEntity> listaMarcas = null;
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();
			FiltrosBean listaPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("active");
			listaPeriodo.setCampos(campoPeriodo);
			listaPeriodo.setOperador("=");
			filtro.add(listaPeriodo);
			valores.add(true);
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			//2.- cargamos las marcas
			listaMarcas =mantenimientoMarcaDao.listaMarcas(filtroSQL);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar marcas de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		List<ProyeccionGeneralMarcasBean> listaProyeccionZonasMarcas = new ArrayList<ProyeccionGeneralMarcasBean>();
		for(MarcaEntity marca: listaMarcas){
			ProyeccionGeneralMarcasBean bean = new ProyeccionGeneralMarcasBean();
			bean.setIdMarca(marca.getId());
			bean.setMarca(validaciones.validarCamposString(marca.getMarca()));
			
			BigDecimal totalMarca = BigDecimal.ZERO;
			try{
				for(ProyeccionZonaDetalleEntity ls : listaProdZona){
					if(marca.getId()==ls.getMarca_id()){
						totalMarca = totalMarca.add(ls.getCantidad_proyectada().multiply(ls.getPrecio_promedio()));
					}
				}
			}catch(Exception e){
				totalMarca = BigDecimal.ZERO;
			}
			bean.setMontoTotal(totalMarca);
			
			if(totalMarca.compareTo(BigDecimal.ZERO) > 0){
				listaProyeccionZonasMarcas.add(bean);
			}
			
		}
		
		if (listaProyeccionZonasMarcas.size() > 0) {
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyeccionZonasMarcas(listaProyeccionZonasMarcas);
		} else {
			System.out.println("No se encontro Datos");
			response.setCodigoRespuesta(ConstModAdministracion.MANT_ELIMINAR_COD_IDF);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_ELIMINAR_MSJ_IDF.replace("msj", mensajeTransaccionMetodo));
		}
		
		return response;
	}

	@Override
	public ListaProyZonasCategoriaResponse mostrarProyZonaCategoria( String codTransaccion, FiltroProductoZonaBean filtrosBean) {
		
		String mensajeTransaccionMetodo = "[mostrarProyZonaMarcas idTx=" + codTransaccion + "] - ";
		ListaProyZonasCategoriaResponse response = new ListaProyZonasCategoriaResponse();
		
		if(filtrosBean.getIdPeriodo() < 1){
			System.out.println("Seleccionar periodo ");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
			return response;
		}
		if(filtrosBean.getIdZona() < 1){
			System.out.println("Seleccionar zona ");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
			return response;
		}
		
		List<ProyeccionZonaDetalleEntity> listaProdZona = null;
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();
			//filtro por periodo
			if(filtrosBean.getIdPeriodo() > 0){
				FiltrosBean listaPeriodo = new FiltrosBean();
				List<String> campoPeriodo = new ArrayList<String>();
				campoPeriodo.add("pz.periodo_id");
				listaPeriodo.setCampos(campoPeriodo);
				listaPeriodo.setOperador("=");
				filtro.add(listaPeriodo);
				valores.add(filtrosBean.getIdPeriodo());
			}
			//filtro por zona
			if(filtrosBean.getIdZona() > 0){
				FiltrosBean listaZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("pz.zona_id");
				listaZona.setCampos(campoZona);
				listaZona.setOperador("=");
				filtro.add(listaZona);
				valores.add(filtrosBean.getIdZona());
			}
			
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			//1.- cargamos la lista de productos por zona y periodo
			listaProdZona = mantProyeccionZonaDetalleDao.listaProyeccionZonaDetalle(filtroSQL);
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar productos de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}

		List<CategoriaProductoEntity> listaCategoriaProd = null;
		try{
			
			//2.- obtenemos la lista de categoria de productos
			listaCategoriaProd = mantCategoriaProductoDao.listarCategoriasProd(null);
			this.listaHijosCategoriaProd = listaCategoriaProd;
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar las proyecciones de categorias productos de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		List<ProyGeneralCategoriaBean> listaCategoriaProy = new ArrayList<ProyGeneralCategoriaBean>();
		for(CategoriaProductoEntity categoria : listaCategoriaProd){
			ProyGeneralCategoriaBean bean = new ProyGeneralCategoriaBean();
			bean.setId(categoria.getId());
			bean.setCategoria(categoria.getNombre());
			bean.setIdPadre(categoria.getPadre_id());
			
			hijos = new ArrayList<CategoriaProductoEntity>();
			//agregamos al padre
			hijos.add(categoria);
			//buscamos sus hijos
			capturarHijos(categoria.getId());
			//buscamos los montos de todos sus hijos
			BigDecimal total = BigDecimal.ZERO;
			try{
				for(CategoriaProductoEntity h :hijos){
					for(ProyeccionZonaDetalleEntity proy : listaProdZona){
						if(h.getId() == proy.getCategoria_producto_id()){
							total =total.add(proy.getPrecio_promedio().multiply(proy.getCantidad_proyectada()));
						}
					}
				}
			}catch(Exception e){
				total = BigDecimal.ZERO;
			}
			
			bean.setMontoTotal(total);
			
			if(total.compareTo(BigDecimal.ZERO) > 0){
				listaCategoriaProy.add(bean);
			}
		}

		if (listaCategoriaProy.size() > 0) {
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyZonasCategoria(listaCategoriaProy);
		} else {
			response.setCodigoRespuesta(ConstModAdministracion.MANT_ELIMINAR_COD_IDF);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_ELIMINAR_MSJ_IDF.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
		
	}
	public void capturarHijos(int idPadre){
		for(CategoriaProductoEntity hijo :listaHijosCategoriaProd){
			if(idPadre == hijo.getPadre_id()){
				hijos.add(hijo);
				capturarHijos(hijo.getId());
			}
		}
	}
}
